package br.ufrgs.meetapp.utils;

import java.io.ByteArrayInputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import br.ufrgs.meetapp.enums.Role;
import br.ufrgs.meetapp.enums.WebServiceResult;
import br.ufrgs.meetapp.models.Buddy;


public class MFTParser {
	
	
	public static WebServiceResult processWebServiceResult(Element documentElement) {
		
		WebServiceResult result = WebServiceResult.UNKNOWN_ERROR;
		
		try {
			NodeList errorCodeNodeList = documentElement.getElementsByTagName("ErrorCode");
			// Assuming there's just one error, get it's id
			Node errorCodeNode = errorCodeNodeList.item(0); 
			
			if (errorCodeNode != null){
				for (int a = 0; a < errorCodeNode.getChildNodes().getLength(); a++) {
					Node errorCodeChild = errorCodeNode.getChildNodes().item(a);
					
					if (errorCodeChild.getNodeName().equals("ID")) {
						result = WebServiceResult.getType(Integer.valueOf(errorCodeChild.getFirstChild().getNodeValue()));
					}
				}
			}
		} catch (Exception exception) {

			System.out.println("Error in MFTParser.processWebServiceResult - trying to parse web service result ");
			if (exception.getMessage() != null)
				System.out.println(exception.getMessage());
			exception.printStackTrace();
		}
		return result;
	}
	
	
	public static ArrayList<Role> processUserRoles(Element documentElement) {
		
		ArrayList<Role> roleCodeList = new ArrayList<Role>();
		
		try {
			NodeList roleNodeList = documentElement.getElementsByTagName("ROLE");
			
			for (int a = 0; a < roleNodeList.getLength(); a++) { 
				
				Node roleNodeListChild = roleNodeList.item(a);
				
				if (roleNodeListChild != null){
					for (int i = 0; i < roleNodeListChild.getChildNodes().getLength(); i++) {
						
						
						if (roleNodeListChild.getChildNodes().item(i) != null && roleNodeListChild.getChildNodes().item(i).getNodeName().equals("ROLE_ID")) {
							Role role = Role.getRole(Integer.valueOf(roleNodeListChild.getChildNodes().item(i).getFirstChild().getNodeValue()));
							if (role != null){
								roleCodeList.add(role);
							}
						}
					}
				}
			}
		} catch (Exception exception) {
			System.out.println("Error in MFTParser.processUserRoles - trying to parse user roles ");
			if (exception.getMessage() != null)
				System.out.println(exception.getMessage());
			exception.printStackTrace();
		}
		
		return roleCodeList;
		
	}
	
	public static int processUserRegisteredDevicesNumber(Element documentElement) {
		
		int registeredDevicesNumber = 0;
		
		try {
			NodeList registeredDevicesNodeList = documentElement.getElementsByTagName("REGISTERED_DEVICES");
			
			Node registeredDevicesNode = registeredDevicesNodeList.item(0);
			
			if (registeredDevicesNode != null) {
				for (int a = 0; a < registeredDevicesNode.getChildNodes().getLength(); a++) {
	
					Node registeredDevicesNodeChild = registeredDevicesNode.getChildNodes().item(a);
					
					if (registeredDevicesNodeChild.getNodeName().equals("TOTAL")) {
						registeredDevicesNumber = Integer.valueOf(registeredDevicesNodeChild.getFirstChild().getNodeValue());
					}
				}
			}
		} catch (Exception exception) {

			System.out.println("Error in MFTParser.processUserRegisteredDevices - trying to parse the number of registered devices ");
			if (exception.getMessage() != null)
				System.out.println(exception.getMessage());
			exception.printStackTrace();
		}
		
		
		return registeredDevicesNumber;
	}
	
	public static int processUserLicenseNumber(Element documentElement) {
		
		int licenseNumber = 0;
		
		try {
			NodeList deviceLicensesNodeList = documentElement.getElementsByTagName("DEVICE_LICENSES");
			
			Node deviceLicensesNode = deviceLicensesNodeList.item(0);
			
			if (deviceLicensesNode != null) {
				for (int a = 0; a < deviceLicensesNode.getChildNodes().getLength(); a++) {
	
					Node deviceLicensesNodeChild = deviceLicensesNode.getChildNodes().item(a);
					
					if (deviceLicensesNodeChild.getNodeName().equals("TOTAL")) {
						licenseNumber = Integer.valueOf(deviceLicensesNodeChild.getFirstChild().getNodeValue());
					}
				}
			}
		} catch (Exception exception) {

			System.out.println("Error in MFTParser.processUserLicenseNumber - trying to parse the user number of licenses ");
		
			if (exception.getMessage() != null)
				System.out.println(exception.getMessage());
			exception.printStackTrace();
		}
		return licenseNumber;
	}
	
	public static ArrayList<Buddy> parseBuddies(String buddiesXMLString) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
		TimeZone tz = TimeZone.getTimeZone("GMT");
		dateFormat.setTimeZone(tz);
		
		ArrayList<Buddy> parsedBuddies = new ArrayList<Buddy>();
		
		try {
			Element node = DocumentBuilderFactory
					.newInstance()
					.newDocumentBuilder()
					.parse(new ByteArrayInputStream(buddiesXMLString.getBytes()))
					.getDocumentElement();
			
			NodeList buddyNodeList = node.getElementsByTagName("RESULT");
			Node currentBuddyNode;
			Node currentContentNode;
			String currentContentNodeText;
			Buddy newBuddy;		
		
			for(int buddyIndex = 0; buddyIndex < buddyNodeList.getLength(); buddyIndex++) {
				currentBuddyNode = buddyNodeList.item(buddyIndex);
				newBuddy = new Buddy();
				
				for(int contentIndex = 0; contentIndex < currentBuddyNode.getChildNodes().getLength(); contentIndex++) {
					
					currentContentNode = currentBuddyNode.getChildNodes().item(contentIndex);
				
					currentContentNodeText = currentContentNode.getTextContent();
					if(currentContentNodeText.equals("\n    "))
						currentContentNodeText = "";
					
					if(currentContentNode.getNodeName().equals("BUDDY_ID"))
						newBuddy.setBuddyId(Integer.parseInt(currentContentNodeText));
					else if(currentContentNode.getNodeName().equals("BUDDY_NAME"))
						newBuddy.setBuddyName(currentContentNodeText);
					else if(currentContentNode.getNodeName().equals("BUDDY_HANDY"))
						newBuddy.setBuddyHandy(currentContentNodeText);
					else if(currentContentNode.getNodeName().equals("BUDDY_EMAIL"))
						newBuddy.setBuddyEmail(currentContentNodeText);
					else if(currentContentNode.getNodeName().equals("LOC_Y")) {
						float latitude = Float.parseFloat(currentContentNodeText);
						newBuddy.setLatitude((int)(latitude * 1E6));
					}
					else if(currentContentNode.getNodeName().equals("LOC_X")) {
						float longitude = Float.parseFloat(currentContentNodeText);
						newBuddy.setLongitude((int)(longitude * 1E6));
					}
					else if(currentContentNode.getNodeName().equals("LOC_RADIUS"))
						newBuddy.setRadius(Integer.parseInt(currentContentNodeText));
					else if(currentContentNode.getNodeName().equals("QUERY_TIME")){
						Date transmissionDate = dateFormat.parse(currentContentNodeText);
				        newBuddy.setTransmissionDate(transmissionDate);
					}
						
					else if(currentContentNode.getNodeName().equals("LOC_TIME")){
						 Date locationDate = dateFormat.parse(currentContentNodeText);
				         newBuddy.setPositionDate(locationDate);
					}
					else if(currentContentNode.getNodeName().equals("PROVIDER_NAME"))
						newBuddy.setProviderName((currentContentNodeText));
					else if(currentContentNode.getNodeName().equals("FUELLEVEL"))
						newBuddy.setBatteryLevel(Integer.parseInt(currentContentNodeText));
					else if(currentContentNode.getNodeName().equals("DEVICE_SERIAL"))
						newBuddy.setDeviceSerial(currentContentNodeText);
				}
				
				parsedBuddies.add(newBuddy);
			}
		} catch (Exception exception) {
			System.out.println("Error in BuddyXMLParser - trying to parse some buddy");
			if(exception.getMessage() != null)
				System.out.println(exception.getMessage());
			exception.printStackTrace();
		}
		
		return parsedBuddies;
	}
}
